import os,requests,re,json
from webvtt import WebVTT
from webvtt.structures import Caption
from pydub import AudioSegment
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
import hashlib

from tooles.ali.ali import Reader

class Worker(object):
    def __init__(self):
        self.ted_url = ""
        self.key = ""
        self.zh_vvt_fn = ""
        self.en_vvt_fn = ""
        self.audio_fn = ""
        self.ali_reader = Reader(212)

        print("init")

    def time_to_milliseconds(self, time_str):
        time_obj = datetime.strptime(time_str, '%H:%M:%S.%f')
        milliseconds = (time_obj.hour * 3600 + time_obj.minute * 60 + time_obj.second) * 1000 + time_obj.microsecond / 1000
        return milliseconds

    def download_file(self, url, file_name):
        "下载文件"
        response = requests.get(url)
        with open(file_name, 'wb') as file:
            file.write(response.content)
        print(f"download:{url}")

    def download_all(self, audios, captions):
        with ThreadPoolExecutor(max_workers=30) as executor:
            for index, item in enumerate(captions):
                executor.submit(self.download_file, audios[index], f"tmp/{self.key}/{index}.mp3")
        print("download_all.done")

    def get_vtt_url(self):
        "获取字幕文件url"
        resp = requests.get(self.ted_url)
        ted_html = resp.text
        pattern = r'(https://[^\"]*?.m3u8\S*?)\\'  # 匹配以 http(s):// 开头，以 .m3u8 结尾的字符串
        m = re.search(pattern, ted_html)
        if m:
            vtt_en_url = m.group(1).replace("manifest.m3u8", "subtitles/en/full.vtt")
            vtt_zh_url = m.group(1).replace("manifest.m3u8", "subtitles/zh-cn/full.vtt")
            print(vtt_en_url, vtt_zh_url)
            return vtt_en_url, vtt_zh_url
        else:
            return None, None

    def get_vtt(self):
        "获取中文字幕内容，如果只有英文字幕，则翻译成中文"
        vtt_en_url, vtt_zh_url = self.get_vtt_url()
        zh_resp = requests.get(vtt_zh_url)
        if len(zh_resp.content) < 100:  # 不包含中文字幕
            en_resp = requests.get(vtt_en_url)
            with open(self.en_vvt_fn, 'wb') as file:
                file.write(en_resp.content)
            self.translate_vtt()
        else:
            with open(self.zh_vvt_fn, 'wb') as file:
                file.write(zh_resp.content)
        print(zh_resp.content)

    def translate_vtt(self):
        "翻译字幕"
        from_vvt = self.en_vvt_fn
        to_vtt = self.zh_vvt_fn
        cmd = """curl -H "Host: yd.transduck.com" -H "accept: application/json, text/plain, */*" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" -H "content-type: application/json" -H "Origin: chrome-extension://oglffgiaiekgeicdgkdlnlkhliajdlja" -H "Sec-Fetch-Site: none" -H "Sec-Fetch-Mode: cors" -H "Sec-Fetch-Dest: empty" -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8" -H "Cookie: youtube-dubbing-user=%7B%22username%22%3A%2229392964%40qq.com%22%7D; SESSION=3d309193-8cd1-4320-911f-860789e57223" --data-binary "#data#" --compressed "https://yd.transduck.com/api/v2/translateAll?language=en&to=zh-CN&videoId=tCTkkHGRpNk"
                """
        vtt = WebVTT().read(from_vvt)
        translated_vtt = WebVTT()
        contents = []
        for caption in vtt.captions:
            print(caption.text)
            contents.append((caption.text))

        data = json.dumps(contents).replace('\\', '\\\\').replace("\"", "\\\"")
        cmd = cmd.replace("#data#", data)
        lines = os.popen(cmd).readlines()
        obj = json.loads("".join(lines))
        contents_to = []
        for item in obj.get("translations"):
            contents_to.append(item.get("text"))

        index = 0
        for caption in vtt.captions:
            translated_vtt.captions.append(Caption(caption.start, caption.end, contents_to[index]))
            index += 1
        translated_vtt.save(to_vtt)

    def read_vtt_1(self):
        "从字幕文件生成语音"
        print("read_vtt")
        cmd = """curl -H "Host: yd.transduck.com" -H "accept: application/json, text/plain, */*" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" -H "content-type: application/json" -H "Origin: chrome-extension://oglffgiaiekgeicdgkdlnlkhliajdlja" -H "Sec-Fetch-Site: none" -H "Sec-Fetch-Mode: cors" -H "Sec-Fetch-Dest: empty" -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8" -H "Cookie: youtube-dubbing-user=%7B%22username%22%3A%2229392964%40qq.com%22%7D; SESSION=3d309193-8cd1-4320-911f-860789e57223" --data-binary "{\\\"voiceName\\\":\\\"zh-CN-YunyangNeural\\\",\\\"subtitles\\\":#data#,\\\"videoId\\\":\\\"tCTkkHGRpNk\\\"}" --compressed "https://yd.transduck.com/api/v2/tts"
            """
        vtt = WebVTT().read(self.zh_vvt_fn)
        contents = []
        captions = vtt.captions
        for caption in captions:
            # print(caption.text)
            contents.append(("\\\"" + caption.text.replace('\\', '').replace("\"", "").replace("\n", " ") + "\\\""))

        data = "[" + ",".join(contents) + "]"
        cmd = cmd.replace("#data#", data)

        lines = os.popen(cmd).readlines()
        audios = json.loads("".join(lines))

        # 下载所有文件
        self.download_all(audios, captions)

        merged_audio = AudioSegment.empty()

        # 遍历 MP3 文件数组
        for index, item in enumerate(audios):
            file_name = f"tmp/{self.key}/{index}.mp3"
            print(file_name)
            # 加载 MP3 文件为 AudioSegment 对象
            audio_segment = AudioSegment.from_mp3(file_name)
            # 将当前音频片段添加到合并后的音频中
            merged_audio += audio_segment
        merged_audio.export(self.audio_fn, format='wav')
        os.popen(f"rm -rf tmp/{self.key}").readlines()
        return self.audio_fn

    def read_vtt(self):
        "从字幕文件生成语音"
        print("read_vtt")
        vtt = WebVTT().read(self.zh_vvt_fn)
        captions = vtt.captions
        merged_audio = AudioSegment.empty()
        for index, item in enumerate(captions):
            txt = item.text.replace('\\', '').replace("\"", "").replace("\n", " ")
            file_name = f"tmp/{self.key}/{index}.mp3"
            self.ali_reader.readtofile(txt, file_name)
            audio_segment = AudioSegment.from_mp3(file_name)
            merged_audio += audio_segment
        merged_audio.export(self.audio_fn, format='wav')
        os.popen(f"rm -rf tmp/{self.key}").readlines()
        return self.audio_fn


    def read_vtt_time(self):
        "从字幕文件生成语音"
        print("read_vtt_time")

        vtt = WebVTT().read(self.zh_vvt_fn)
        captions = vtt.captions
        duration = self.time_to_milliseconds(captions[len(captions) - 1].end)
        audio = AudioSegment.silent(duration=duration)
        end = 0  # 实际结束时间点
        for index, item in enumerate(captions):
            try:
                txt = item.text.replace('\\', '').replace("\"", "").replace("\n", " ")
                file_name = f"tmp/{self.key}/{index}.mp3"
                self.ali_reader.readtofile(txt, file_name)
                v = AudioSegment.from_file(file_name)
                if end > self.time_to_milliseconds(item.start):
                    v = v.speedup(playback_speed=1.2)
                real_l = len(v)  # 实际长度
                if end + real_l > self.time_to_milliseconds(item.end):
                    audio = audio.overlay(v, position=end)
                    end = end + real_l
                    print(f"{index}/{len(captions)}/01:{end - self.time_to_milliseconds(item.start)}")
                elif end < self.time_to_milliseconds(item.start):
                    if self.time_to_milliseconds(item.end) - self.time_to_milliseconds(item.start) > real_l:
                        audio = audio.overlay(v, position=self.time_to_milliseconds(item.start))
                        end = self.time_to_milliseconds(item.start) + real_l
                        print(f"{index}/{len(captions)}/02:")
                    else:
                        audio = audio.overlay(v, position=self.time_to_milliseconds(item.end) - real_l)
                        end = self.time_to_milliseconds(item.end)
                        print(f"{index}/{len(captions)}/03:{self.time_to_milliseconds(item.end) - real_l - self.time_to_milliseconds(item.start)}")

            except Exception as e:
                print(e)
        audio.export(self.audio_fn, format='wav')
        os.popen(f"rm -rf tmp/{self.key}").readlines()
        return ""

    def read_vtt_time_2(self):
        "从字幕文件生成语音"
        print("read_vtt_time")
        m3u8 = """#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-MEDIA-SEQUENCE:0\n#EXT-X-TARGETDURATION:10\n#EXT-X-PLAYLIST-TYPE:VOD\n"""

        cmd = """curl -H "Host: yd.transduck.com" -H "accept: application/json, text/plain, */*" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" -H "content-type: application/json" -H "Origin: chrome-extension://oglffgiaiekgeicdgkdlnlkhliajdlja" -H "Sec-Fetch-Site: none" -H "Sec-Fetch-Mode: cors" -H "Sec-Fetch-Dest: empty" -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8" -H "Cookie: youtube-dubbing-user=%7B%22username%22%3A%2229392964%40qq.com%22%7D; SESSION=3d309193-8cd1-4320-911f-860789e57223" --data-binary "{\\\"voiceName\\\":\\\"zh-CN-YunyangNeural\\\",\\\"subtitles\\\":#data#,\\\"videoId\\\":\\\"tCTkkHGRpNk\\\"}" --compressed "https://yd.transduck.com/api/v2/tts"
                """
        vtt = WebVTT().read(self.zh_vvt_fn)
        contents = []
        captions = vtt.captions
        for caption in captions:
            # print(caption.text)
            contents.append(("\\\"" + caption.text.replace('\\', '').replace("\"", "").replace("\n", " ") + "\\\""))

        data = "[" + ",".join(contents) + "]"
        cmd = cmd.replace("#data#", data)
        print(cmd)
        lines = os.popen(cmd).readlines()
        audios = json.loads("".join(lines))
        print(audios)
        strs = []
        for audio in audios:
            strs.append("")
            strs.append("#EXTINF:10.0,")
            strs.append(audio)
        print(strs)
        m3u8 += "\n".join(strs)
        print(m3u8)

        file_name = self.audio_fn
        with open(file_name, 'w') as file:
            file.write(m3u8)
        print(f"download:{file_name}")

        return file_name

    def read_vtt_time_1(self):
        "从字幕文件生成语音"
        print("read_vtt_time")
        cmd = """curl -H "Host: yd.transduck.com" -H "accept: application/json, text/plain, */*" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" -H "content-type: application/json" -H "Origin: chrome-extension://oglffgiaiekgeicdgkdlnlkhliajdlja" -H "Sec-Fetch-Site: none" -H "Sec-Fetch-Mode: cors" -H "Sec-Fetch-Dest: empty" -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8" -H "Cookie: youtube-dubbing-user=%7B%22username%22%3A%2229392964%40qq.com%22%7D; SESSION=3d309193-8cd1-4320-911f-860789e57223" --data-binary "{\\\"voiceName\\\":\\\"zh-CN-YunyangNeural\\\",\\\"subtitles\\\":#data#,\\\"videoId\\\":\\\"tCTkkHGRpNk\\\"}" --compressed "https://yd.transduck.com/api/v2/tts"
        """
        vtt = WebVTT().read(self.zh_vvt_fn)
        contents = []
        captions = vtt.captions
        for caption in captions:
            # print(caption.text)
            contents.append(("\\\"" + caption.text.replace('\\', '').replace("\"", "").replace("\n", " ") + "\\\""))

        data = "[" + ",".join(contents) + "]"
        cmd = cmd.replace("#data#", data)
        # print(cmd)
        lines = os.popen(cmd).readlines()
        audios = json.loads("".join(lines))

        print(audios)

        # 下载所有文件
        self.download_all(audios, captions)

        duration = self.time_to_milliseconds(captions[len(captions) - 1].end)
        audio = AudioSegment.silent(duration=duration)
        end = 0  # 实际结束时间点

        for index, item in enumerate(captions):
            try:
                file_name = f"tmp/{self.key}/{index}.mp3"
                # get_file(audios[index],file_name)
                v = AudioSegment.from_file(file_name)
                if end > self.time_to_milliseconds(item.start):
                    v = v.speedup(playback_speed=1.2)
                real_l = len(v)  # 实际长度
                if end + real_l > self.time_to_milliseconds(item.end):
                    audio = audio.overlay(v, position=end)
                    end = end + real_l
                    print(f"01:{end - self.time_to_milliseconds(item.start)}")
                elif end < self.time_to_milliseconds(item.start):
                    if self.time_to_milliseconds(item.end) - self.time_to_milliseconds(item.start) > real_l:
                        audio = audio.overlay(v, position=self.time_to_milliseconds(item.start))
                        end = self.time_to_milliseconds(item.start) + real_l
                        print(f"02:0")
                    else:
                        audio = audio.overlay(v, position=self.time_to_milliseconds(item.end) - real_l)
                        end = self.time_to_milliseconds(item.end)
                        print(f"03:{self.time_to_milliseconds(item.end) - real_l - self.time_to_milliseconds(item.start)}")

            except Exception as e:
                print(e)
        audio.export(self.audio_fn, format='wav')
        os.popen(f"rm -rf tmp/{self.key}").readlines()
        return ""

    def proc(self, ted_url):
        print(ted_url)
        if ted_url.find("?") > 0:
            ted_url = ted_url[:ted_url.find("?")]

        self.ted_url = ted_url
        self.key = hashlib.md5(self.ted_url.encode()).hexdigest()
        self.en_vvt_fn = f"tmp/{self.key}/en_vvt_{self.key}.vtt"
        self.zh_vvt_fn = f"tmp/{self.key}/zh_vvt_{self.key}.vtt"
        self.audio_fn = self.get_audio_fn(ted_url)
        os.popen(f"mkdir -p tmp/{self.key}").readlines()
        os.popen(f"mkdir -p output").readlines()

        if not os.path.exists(self.audio_fn) and not os.path.exists(self.en_vvt_fn):
            try:
                self.get_vtt()
                self.read_vtt_time()
                # self.read_vtt_time_2()
            except Exception as e:
                os.popen(f"rm -rf tmp/{self.key}").readlines()
                print(e)
        # print(self.audio_fn)
        return self.audio_fn
    def get_audio_fn(self, ted_url):
        if ted_url.find("?") > 0:
            ted_url = ted_url[:ted_url.find("?")]
        key = hashlib.md5(ted_url.encode()).hexdigest()
        return f"static/out_{key}.wav"



if __name__ == "__main__":
    worker = Worker()
    ted_url = "https://www.ted.com/talks/ismael_nazario_what_i_learned_as_a_kid_in_jail?showTranscriptTooltip=true"
    worker.proc(ted_url)
